package io.rocketman.transport.channel;

import io.rocketman.config.client.ClientMetaData;
import io.rocketman.config.server.ServerMetaData;
import io.rocketman.transport.ChannelClosedException;
import io.rocketman.transport.NetworkTransportException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.net.InetSocketAddress;
import java.util.concurrent.Future;

/**
 * @author He Peng
 * @create 2018-05-25 1:26
 * @update 2018-05-25 1:26
 * @updatedesc : 更新说明
 * @see
 */

@NoArgsConstructor
@AllArgsConstructor
@Data
public abstract class AbstractChannel implements Channel {

    protected Boolean isClose;
    protected Boolean isOpen;
    protected InetSocketAddress remoteAddress;
    protected InetSocketAddress localAddress;
    protected ServerMetaData serverMetaData;
    protected ClientMetaData clientMetaData;

    @Override
    public void close() {
        if (isOpen()) {
            doClose();
        }
    }

    @Override
    public Future send(Object message) throws NetworkTransportException {
        checkChannelNotClosed(message);
        return doSend(message);
    }

    private void checkChannelNotClosed(Object message) throws ChannelClosedException {
        if (isClose()) {
            throw new ChannelClosedException(this, "Failed to send message "
                    + (message == null ? "" : message.getClass().getName()) + ":" + message
                    + ", cause: Channel closed. channel: " + getLocalAddress() + " -> " + getRemoteAddress());
        }
    }

    protected abstract void doClose();

    protected abstract Future<Object> doSend(Object message);
}
